﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Modele;
using System.Collections;
        
/**
* @author Quentin Leguay 4Info INSA Rennes 
* @date Avril 2010
* @brief La classe PAN est la classe qui contient le MVC
*/
namespace general{ 

    public class Logiciel
    {
        /***************/
        /** attributs **/
        /***************/

        // Les 3 parties du MVC
        private vue.Vue vue;
        private Modele.Modele modele;
        private Controleur.Controleur controleur;



        /***************/
        /**  méthodes **/
        /***************/

        //Constructeur
        public Logiciel() {
        modele = new Modele.Modele(this);
        vue = new vue.Vue(this);
        controleur = new Controleur.Controleur(this);
        
                
        }

        //Accesseurs
        public Controleur.Controleur getControleur()
        {
            return controleur;
        }

        public  void Run()
        {
            vue.Run();
        }



        /*****************/
        /**  Controleur **/
        /*****************/

        /**
         * @brief Appel aux actions des modes
         * @param Strokes _strokes : objet contenant de nombreuses informations (analogue à ensemble de points)
         * @return void
        */
        public void ActionZoneDessin(Microsoft.Ink.Stroke _stroke)
        {
            controleur.ActionZoneDessin(_stroke);
        }

        // clic sur le bouton sur le côté du stylet
        public void ActionBouton()
        {
            controleur.ActionBouton();
        }

        // tracer un trait sur la zone de dessin avec la "gomme"
        public void ActionEffacer(Microsoft.Ink.Strokes _strokes)
        {
            controleur.ActionEffacer(_strokes);
        }


        public void ActionDoubleClic(Microsoft.Ink.Strokes _strokes)
        {
            controleur.ActionDoubleClic(_strokes);
        }

        public void changerMode(Controleur.Mode _mode)
        {
            controleur.changerMode(_mode);
        }


        // Change la couleur du mode
        public void setModeCouleur(System.Drawing.Color _couleur)
        {
            if(controleur.setModeCouleur(_couleur)){
                vue.completeRefresh();
            }
        }

        // Change l'opacité du mode
        public void setModeOpacite(int _opacite)
        {
            if (controleur.setModeOpacite(_opacite))
            {
                vue.completeRefresh();
            }
        }

        // Change l'épaisseur du mode
        public void setModeEpaisseur(int _epaisseur)
        {
            if (controleur.setModeEpaisseur(_epaisseur))
            {
                vue.completeRefresh();
            }
        }

        public void changerCalqueCourant(int numero_calque)
        {
            controleur.changerCalqueCourant(numero_calque);        
            vue.completeRefresh();
        }


        public void creeCalque()
        {
             controleur.creeCalque();
        }


        /**
        * @brief undo
        * @brief remontée de l'évènement undo
        * @param int nb : le nombre d'annulations (actuellement 0)
        * @return int nb : le nombre d'annulations réalisées
        */
        public int undo(int _nb)
        {
            return controleur.undo(_nb);
        }



        /**
        * @brief redo
        * @brief remontée de l'évènement redo
        * @param int nb : le nombre d'annulations (actuellement 0)
        * @return int nb : le nombre d'annulations refaites
        */
        public int redo(int _nb)
        {
            return controleur.redo(_nb);
        }

        /**
        * @brief sendUtilisateur
        * @brief remontée de l'utilisateur
        * @param string _prenom : le prénom de l'utilisateur
        * @param string _nom : le nom de l'utilisateur
        * ArrayList : la liste de tous les utilisateurs enregistrés
        */
        public ArrayList sendUtilisateur(string _prenom,string _nom)
        {
            controleur.setPrenomUtilisateur(_prenom);
            controleur.setNomUtilisateur(_nom);
            return modele.sendUtilisateur(_prenom, _nom);
        }



        /***************/
        /**    Vue    **/
        /***************/

       /**
        * @brief rafraichirVue
        * @brief demande à la vue de se rafraichir
        * @return void
       */
       public void rafraichirVue(){
           vue.refresh();
        }

       /**
        * @brief rafraichirVue
        * @brief demande à la vue de se rafraichir
        * @return void
        */
        public void completeRefresh()
        {

            // MAJ du claque courant
            vue.completeRefresh(modele.getCalqueCourant().getInk(),
                                modele.getCalqueCourant().getAnnotations() ,
                                modele.getCalqueCourant().getTextes());

            vue.changerGraphics(modele.getCombinedInk(),
                                modele.getCombinedAnnotations(),
                                modele.getCombinedTexte());

            //Console.WriteLine("completeRefresh logiciel");
            // SUITE DES MAJ à faire


        }


        /**
            * setDrawingAttributes()
            *
            * @brief envoie un nouveau DrawingAttributes à la vue
            * @return void
        */
        public void setDrawingAttributes(Microsoft.Ink.DrawingAttributes _att)
        {
            vue.setDrawingAttributes(_att);
        }


        public Bitmap toImage(System.Drawing.Image im, float zoom)
        {
            Console.WriteLine("entrer dans toimage");
            using (Graphics graph = Graphics.FromImage(im))
            {
                
                Microsoft.Ink.Renderer rend = new Microsoft.Ink.Renderer();
                modele.getCombinedInk().Strokes.Scale(zoom, zoom);
                rend.Draw(graph, modele.getCombinedInk().Strokes);
                //g.DrawImage
                Point tampon;
                int i = 0; //variable de test

                ArrayList annot = modele.getCombinedAnnotations();
                ArrayList text = modele.getCombinedTexte();



                //ecriture des textes


                IEnumerator it = text.GetEnumerator();
                string texte_a_ajouter = "";
                Font police = new Font("Arial", 16);
                System.Drawing.Brush brush = new SolidBrush(Color.Black);
                i = 0;
                double x;
                double y;
                while (it.MoveNext())
                {
                    i++;
                    //ajout du texte au graphics
                    texte_a_ajouter = ((Texte)it.Current).getIcone();
                    //conversion echelles différents entre le inkpicture et l ecran : 
                    x = ((Texte)it.Current).getPoint().X * (double)zoom / (25.4);
                    y = ((Texte)it.Current).getPoint().Y * (double)zoom / (25.4);
                    Console.WriteLine("ToImage : Affichage du texte suivante : {0}", texte_a_ajouter);
                    graph.DrawString(texte_a_ajouter, police, brush, new Point((int)x, (int)y));

                    Console.WriteLine("ToImage : Ajoute du texte {0} / numero {1}", ((Texte)it.Current).getIcone(), i);
                }

                it = modele.getProjet().getCalqueCourant().getTextes().GetEnumerator();

                while (it.MoveNext())
                {
                    i++;
                    //ajout du texte au graphics
                    texte_a_ajouter = ((Texte)it.Current).getIcone();
                    //conversion echelles différents entre le inkpicture et l ecran : 
                    x = ((Texte)it.Current).getPoint().X * (double)zoom / (25.4);
                    y = ((Texte)it.Current).getPoint().Y * (double)zoom / (25.4);
                    Console.WriteLine("ToImage : Affichage du texte suivante : {0}", texte_a_ajouter);
                    graph.DrawString(texte_a_ajouter, police, brush, new Point((int)x, (int)y));

                    Console.WriteLine("ToImage : Ajoute du texte {0} / numero {1}", ((Texte)it.Current).getIcone(), i);
                }

                it = annot.GetEnumerator();


                while (it.MoveNext())
                {
                    i++;
                    graph.DrawImage(((Balise)it.Current).getIcone(), (float)(((Balise)it.Current).getPoint().X * zoom/(25.4)),(float) (((Balise)it.Current).getPoint().Y * zoom/(25.4)));
                }

                it = modele.getProjet().getCalqueCourant().getAnnotations().GetEnumerator();

                while (it.MoveNext())
                {
                    i++;
                    graph.DrawImage(((Balise)it.Current).getIcone(), (float)(((Balise)it.Current).getPoint().X * zoom / (25.4)), (float)(((Balise)it.Current).getPoint().Y * zoom / (25.4)));
                   
 
                    //ecriture de l'encre
                }
                Bitmap bmp = new Bitmap(im);
                Console.WriteLine("sortir de toimage");
                return bmp;
            }
        }

        //ajout de la balise et de l'image en grande qualité dans la bibliothèque de la sdd
        public void addBibliothequeBalise(Modele.Balise _balise, System.Drawing.Bitmap new_image_balise)
        {
            modele.addBibliothequeBalise(_balise, new_image_balise);
        }

        /*
         * supprime le calque courant
         */
        public void supprimerCalqueCourant()
        {
            controleur.supprimerCalqueCourant();
        }

       /************
       ** Modèle **
       ************/

        /**
        * @brief addKeyWord
        * @brief ajoute un mot-clef à la liste de mot-clefs
        * @return ArrayList listKeyWords : la liste des mot-clefs du modèle
        */
        public ArrayList addKeyWord(string _dialogue)
        {
            return modele.addKeyWord(_dialogue);
        }

       /**
       * @brief analyserStroke
       * @brief demande au logiciel de reconnaitre un stroke
       * @return bool reconnu : indique si le stroke a été reconnu ou non
       */
       public bool analyserStroke(Microsoft.Ink.Stroke _stroke)
       {
           bool reconnu = modele.analyserStroke(_stroke);
           return reconnu;
       }


       /**
        *  @brief addStroke
        *  @brief ajoute un Stroke dans la SDD
        *  @return void
       */
       public List<Microsoft.Ink.Stroke> addStroke(Microsoft.Ink.Stroke _stroke)
       {
           return modele.addStroke(_stroke);
       }

        /**
        *  @brief addInk
        *  @brief ajoute un Ink dans la SDD
        *  @return void
        */
       public List<Microsoft.Ink.Stroke> addInk(Microsoft.Ink.Ink _ink, Microsoft.Ink.DrawingAttributes _attributes)
       {
           return modele.addInk(_ink, _attributes);
       }

       /**
        *  @brief addBalise
        *  @brief ajoute une balise dans la SDD
        *  @return void
        */
       public void addBalise(Balise _balise)
       {
           modele.addBalise(_balise);
       }

       /**
       *  @brief getCalqueCourant()
       *  @brief retourne le calqueCourant
       *  @return Calque : le calque courant
       */
       public Modele.Calque getCalqueCourant()
       {
           return modele.getCalqueCourant();
       }

       public vue.Vue getVue()
       {
           return vue;
       }
        
       public void changeVisibility(int numero_calque)
       {
           modele.changeVisibility(numero_calque);
       }
        /**
        *  @brief deleteStrokes
        *  @brief enlève un Stroke dans la SDD
        *  @return void
       */
        /*
       public void deleteStroke(Microsoft.Ink.Stroke _stroke)
       {
           modele.deleteStroke(_stroke);
       }
        */

       /**
        *  @brief getProjetBlocNote
        *  @brief envoi un pointeur vers le projetBlocNote
        *  @return ProjetBlocNote : le projetBlocNote du modèle
        */
       public Modele.ProjetBlocNote getProjetBlocNote()
       {
           return modele.getProjet();
       }

       /*
        * Ouvre un nouveau projet
        */
       public void ouvertureNouveauProjet()
       {
           modele = new Modele.Modele(this);
           controleur = new Controleur.Controleur(this);
       }

       //permet d'obtenir le list de bool correspondant aux calque et à leur état associé
       public List<bool> getEtatsCalques()
       {
           return modele.getEtatsCalques();
       }


               //GESTION DES NOMS DES CALQUES 
        public List<string> getNoms()
        {
            return modele.getNoms();
        }
        //retourne le nom du calque numero i
        public string getNom(int i)
        {
            return modele.getNom(i);
        }
        //change le non du claque numero i 
            public void setNom(int i , string _nom)
        {
            modele.setNom(i ,_nom);
        }

        //change le non du claque courant 
         public void setNom( string _nom)
         {
           modele.setNom(_nom);
         }


        /*****************/
        /**  Accesseurs **/
        /*****************/


       /**
        *  @brief getModele
        *  @brief envoi un pointeur vers le modèle. Attention, ne pas faire n'importe quoi avec
        *  @return Modele : modele du logiciel
        */
       public Modele.Modele getModele()
       {
           return modele;
       }

        /**
        *  clear_balise()
        *  
        *  @brief Enlève toutes les balises du calque courant
        *  @return void
        */
       public void clear_balise()
       {
           controleur.clear_balise();
           this.completeRefresh();
       }

        /**
        *  clear_encre()
        *  
        *  @brief Enlève toute l'encre du calque courant
        *  @return void
        */
       public void clear_encre()
       {
           controleur.clear_encre();
           this.completeRefresh();
       }

       /**
       *  clear_texte()
       *  
       *  @brief Enlève tous les textes du calque courant
       *  @return void
       */
       public void clear_texte()
       {
           controleur.clear_texte();
           this.completeRefresh();
       }

       /*****************/
       /**  Recherche  **/
       /*****************/

       /**
        *  @brief List<System.Drawing.Point> lancer_recherche
        *  @brief permet de lancer la recherche et recupere la list de positions des objets trouvés
        *  @return List<System.Drawing.Point>
        */
       public List<System.Drawing.Point> lancer_recherche(bool recherche_dans_balise,
                                             bool recherche_dans_encre,
                                             bool recherche_dans_texte,
                                             string mot_cle,
                                             string auteur,
                                             bool rechercheCalqueCourant)
                       {
                           return controleur.lancer_recherche(recherche_dans_balise,
                                                                      recherche_dans_encre,
                                                                      recherche_dans_texte,
                                                                      mot_cle,
                                                                      auteur,
                                                                      rechercheCalqueCourant);
                       }

        public List<System.Drawing.Point> lancer_recherche(bool recherche_dans_balise,
                                             bool recherche_dans_encre,
                                             bool recherche_dans_texte,
                                             Modele.Semantique sem,
                                             bool rechercheCalqueCourant)
                       {
                           return controleur.lancer_recherche(recherche_dans_balise,
                                                                      recherche_dans_encre,
                                                                      recherche_dans_texte,
                                                                      sem,
                                                                      rechercheCalqueCourant);
                       }




       public void sauver(String nomFichier)
       {
           modele.sauver(nomFichier);
       }

       //mise a jour de la sdd (document)
       public void ajouterDocument(System.Drawing.Bitmap document)
       {
           modele.ajouterDocument(document);
       }

       public Bitmap ouvrir(String nomFichier)
       {
           return modele.ouvrir(nomFichier);
       }

       //switch vers le blocnote
       public System.Drawing.Bitmap changer_vers_blocnote()
       {
           System.Drawing.Bitmap tampon = modele.changer_vers_blocnote();
           controleur.changer_vers_blocnote();
           return tampon;
       }

       //switch vers le projet
       public System.Drawing.Bitmap changer_vers_projet()
       {
           System.Drawing.Bitmap tampon = modele.changer_vers_projet();
           controleur.changer_vers_projet();
           return tampon;
       }

       public void setBibliImages(List<Bitmap> images_balises)
       {
           modele.setBibliImages(images_balises);
       }

       public void setBibliBalises(List<Balise> balises)
       {
           modele.setBibliBalises(balises);
       }

       public List<Bitmap> getBibliImages()
       {
           return modele.getBibliImages();
       }

       public List<Balise> getBibliBalises()
       {
           return modele.getBibliBalises();
       }

    }
}
